package chaoyue.study.pool;

import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.RecursiveTask;

/**
 * ForkJoinPool
 * 把一个大任务分割成诺干小任务，再对每个小任务的计算结果进行汇总，最终得到大任务的结果。
 * Fork：任务拆分
 * Join：结果合并
 * ForkJoinTask：职责相当于Future，定义需要提交给ForkJoinPool执行的任务
 * RecursiveTask：ForkJoinTask的子类，用来处理有返回值的任务
 * RecursiveAction：ForkJoinTask的子类，用来处理无返回值的任务
 */
public class ForkJoinPoolTest {
    public static void main(String[] args) throws Exception {
        // 创建任务
        Task task = new Task(1, 100);
        // 创建ForkJoin线程池
        ForkJoinPool pool = new ForkJoinPool();
        // 提交任务
        ForkJoinTask<Integer> future = pool.submit(task);
        // 获取结果
        System.out.println(future.get());
        pool.shutdown();
    }

    /**
     * 处理有返回值的任务
     * 这边演示从1加到100求和
     */
    private static class Task extends RecursiveTask<Integer> {
        // 累加任务起始值
        private int start;
        // 累加任务结束值
        private int end;
        // 每个任务处理多少个数字
        private int temp = 10;

        public Task(int start, int end) {
            this.start = start;
            this.end = end;
        }

        /**
         * 处理逻辑，任务分割和任务计算的代码都写在这里
         */
        @Override
        protected Integer compute() {
            // 起始和结束只差小于临界值，表示任务不需要再拆分了，开始进行计算
            if ((end - start) < temp) {
                System.out.println(Thread.currentThread().getName() + " start: " + start + " ,end: " + end);
                int sum = 0;
                for (int i = start; i <= end; i++) {
                    sum += i;
                }
                return sum;
            } else {
                // 任务分割，从中间分割成2个小任务，分割任务的数量时可以自己决定的
                int middle = (start + end) / 2;
                Task task1 = new Task(start, middle);
                Task task2 = new Task(middle + 1, end);
                // 向线程池中添加任务
                task1.fork();
                task2.fork();
                // 合并结果
                return task1.join() + task2.join();
            }
        }
    }
}
